Conversation
WalkthroughAdds a new Go benchmark tool and integrates it into CI: new Changes
Sequence Diagram(s)sequenceDiagram
participant CI as CI Driver
participant Script as Bash Orchestrator
participant Eloq as EloqDoc Server
participant Bench as bench_doc (Go)
participant Mongo as MongoDB
participant Disk as FileSystem
participant Art as Artifacts
CI->>Script: start pipeline
Script->>Eloq: launch EloqDoc (phase start)
Script->>Eloq: run_tpcc()
Eloq->>Mongo: execute TPCC workload
Mongo-->>Eloq: results
Script->>Mongo: drop TPCC DB
Script->>Eloq: shutdown
Script->>Bench: run_bench_go (build & run)
Bench->>Disk: generate document files
Disk-->>Bench: files available
Bench->>Mongo: load batches & run inserts
Mongo-->>Bench: acks / latencies
Bench->>Mongo: run query suites (warmup + measured)
Mongo-->>Bench: query results / latencies
Bench->>Mongo: drop benchmark DB
Bench->>Art: export JSON/CSV
Bench-->>Script: exit
Script->>Eloq: final launch for jstests
Script->>Eloq: run_jstests()
Script->>Eloq: shutdown & cleanup
Art-->>CI: upload artifacts
Estimated Code Review Effort🎯 4 (Complex) | ⏱️ ~50 minutes
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (4)
concourse/scripts/common.sh (1)
286-294: Consider adding error handling for the build and execution steps.The function runs
go buildand executes the benchmark without checking for failures. If the build fails, the execution will also fail, potentially with confusing error messages.🔎 Proposed fix with error handling
run_bench_go() { pushd /home/$current_user/workspace/mongo/tests/gotests/bench_doc echo "build bench_doc" - go build + if ! go build; then + echo "Error: Failed to build bench_doc" + popd + return 1 + fi echo "run bench_doc" ./bench_doc -eloqdoc-only $PREFIX/bin/eloqdoc-cli benchmark_db_11 --eval "db.dropDatabase()" popd }concourse/scripts/main.ent.bash (1)
57-66: Consider adding cleanup between test phases for robustness.The script launches and shuts down EloqDoc multiple times without cleanup between phases (lines 57-61 and 62-66). If
shutdown_eloqdocfails or leaves processes running, the subsequentlaunch_eloqdoccould encounter port conflicts or resource issues.Consider adding a cleanup step between phases:
launch_eloqdoc "$BUCKET_NAME" "$BUCKET_PREFIX" try_connect run_tpcc shutdown_eloqdoc +cleanup_all "$DATA_DIR" "$BUCKET_NAME" "$BUCKET_PREFIX" launch_eloqdoc "$BUCKET_NAME" "$BUCKET_PREFIX" try_connect run_bench_go shutdown_eloqdoc +cleanup_all "$DATA_DIR" "$BUCKET_NAME" "$BUCKET_PREFIX" launch_eloqdoc "$BUCKET_NAME" "$BUCKET_PREFIX"This ensures a clean state between test phases and reduces the risk of interference.
tests/gotests/bench_doc/main.go (2)
26-39: Consider making connection URIs and database configuration externally configurable.The URIs, database name, and other configuration constants are hardcoded. For a benchmarking tool that may need to run in different environments or configurations, consider using environment variables or command-line flags.
🔎 Example approach using environment variables with defaults
// Configuration constants const ( - mongoURI = "mongodb://127.0.0.1:17017" - eloqdocURI = "mongodb://127.0.0.1:27017" - dbName = "benchmark_db_11" singleInsertCount = 100 batchSize = 100 numBatches = 100 maxRetries = 4 retryDelayMs = 10000 loaderThreads = 3 benchmarkDataDir = "./benchmark_data" deleteBatchSize = 500 ) + +// Get configuration from environment or use defaults +var ( + mongoURI = getEnv("MONGO_URI", "mongodb://127.0.0.1:17017") + eloqdocURI = getEnv("ELOQDOC_URI", "mongodb://127.0.0.1:27017") + dbName = getEnv("DB_NAME", "benchmark_db_11") +) + +func getEnv(key, defaultValue string) string { + if value := os.Getenv(key); value != "" { + return value + } + return defaultValue +}
371-387: Review the exponential backoff implementation.The retry logic uses exponential backoff with
retryDelayMs*(1<<uint(attempt-1)). ForretryDelayMs=10000(10 seconds):
- Attempt 1: 10s delay
- Attempt 2: 20s delay
- Attempt 3: 40s delay
- Attempt 4: 80s delay
This totals 150 seconds of retry delays for 4 retries, which may be excessive for a benchmark tool where fast failure might be preferable.
Consider either:
- Reducing
retryDelayMsormaxRetries- Using a capped exponential backoff
- Making retry behavior configurable for different operation types
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
tests/gotests/bench_doc/go.sumis excluded by!**/*.sum
📒 Files selected for processing (4)
concourse/scripts/common.shconcourse/scripts/main.ent.bashtests/gotests/bench_doc/go.modtests/gotests/bench_doc/main.go
🧰 Additional context used
🧬 Code graph analysis (1)
concourse/scripts/main.ent.bash (1)
concourse/scripts/common.sh (7)
launch_eloqdoc(188-210)try_connect(241-262)run_tpcc(270-284)shutdown_eloqdoc(237-239)run_bench_go(286-294)run_jstests(264-268)cleanup_all(68-84)
🪛 Gitleaks (8.30.0)
tests/gotests/bench_doc/main.go
[high] 441-441: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
[high] 475-475: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
🪛 OSV Scanner (2.3.0)
tests/gotests/bench_doc/go.mod
[CRITICAL] 1-1: golang.org/x/crypto 0.26.0: Misuse of connection.serverAuthenticate may cause authorization bypass in golang.org/x/crypto
(GO-2024-3321)
[CRITICAL] 1-1: golang.org/x/crypto 0.26.0: Potential denial of service in golang.org/x/crypto
(GO-2025-3487)
[CRITICAL] 1-1: golang.org/x/crypto 0.26.0: Potential denial of service in golang.org/x/crypto/ssh/agent
(GO-2025-4116)
[CRITICAL] 1-1: golang.org/x/crypto 0.26.0: Unbounded memory consumption in golang.org/x/crypto/ssh
(GO-2025-4134)
[CRITICAL] 1-1: golang.org/x/crypto 0.26.0: Malformed constraint may cause denial of service in golang.org/x/crypto/ssh/agent
(GO-2025-4135)
[CRITICAL] 1-1: golang.org/x/crypto 0.26.0: golang.org/x/crypto/ssh/agent vulnerable to panic if message is malformed due to out of bounds read
[CRITICAL] 1-1: golang.org/x/crypto 0.26.0: golang.org/x/crypto Vulnerable to Denial of Service (DoS) via Slow or Incomplete Key Exchange
[CRITICAL] 1-1: golang.org/x/crypto 0.26.0: golang.org/x/crypto/ssh allows an attacker to cause unbounded memory consumption
[CRITICAL] 1-1: golang.org/x/crypto 0.26.0: Misuse of ServerConfig.PublicKeyCallback may cause authorization bypass in golang.org/x/crypto
🔇 Additional comments (7)
concourse/scripts/common.sh (1)
282-284: LGTM! Good addition of cleanup logic.The database cleanup after TPCC execution and the matching
popdproperly balance the directory navigation. This ensures the database is cleaned up and the working directory is restored.tests/gotests/bench_doc/main.go (6)
441-441: False positive: Static analysis flagged test data as secrets.The static analysis tool flagged lines 441 and 475 as potential API keys. However, these are dummy test data strings used to generate realistic benchmark documents, not actual secrets. The string
"hWN4vswT9UEwPM1iWZDVx6FO?key=f6de207245be7cd84be6a4738fc3d749"is part of the Cart struct initialization for document generation.Also applies to: 475-475
582-676: LGTM! Well-designed concurrent document loading.The
loadDocumentsInBatchesfunction demonstrates good practices:
- Worker pool pattern with configurable workers
- Context cancellation support for early termination
- Buffered channels to avoid blocking
- Proper cleanup with WaitGroup
The concurrent loading should provide good performance for the benchmark data preparation phase.
732-846: Good structure with comprehensive setup and verification.The
benchmarkDatabasefunction properly:
- Configures MongoDB client with appropriate timeouts and pool sizes
- Verifies connection with ping
- Sets up collections with retry logic
- Loads documents in batches with progress reporting
- Verifies document counts
- Prepares separate document sets for different benchmark types
The approach is thorough and handles potential failures gracefully.
1057-1065: Most query types are commented out, limiting benchmark coverage.Only "Exact Match" queries are active in the benchmark. The other query types (Range, AND, OR, Array Contains, Nested Field, Complex) are commented out, which significantly reduces the comprehensiveness of the query benchmarks.
Is this intentional for the initial PR, or should these query types be enabled? If they're disabled due to issues, consider documenting the reason or creating a follow-up task to enable them.
1276-1292: LGTM! Correct percentile calculation with linear interpolation.The percentile function properly implements linear interpolation between adjacent values, which provides more accurate percentile estimates than simple index-based selection. The boundary checks for empty and single-element arrays are also correct.
1462-1494: Cleanup functions properly handle errors and provide feedback.Both
cleanupCollectionsandcleanupFoldersinclude:
- Proper error handling with logging
- Success confirmation messages
- Continuation despite individual failures
This ensures the cleanup process is robust and informative.
| github.com/xdg-go/scram v1.1.2 // indirect | ||
| github.com/xdg-go/stringprep v1.0.4 // indirect | ||
| github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect | ||
| golang.org/x/crypto v0.26.0 // indirect |
There was a problem hiding this comment.
Update golang.org/x/crypto to address security vulnerabilities.
golang.org/x/crypto v0.26.0 is affected by CVE-2024-45337, which allows authorization bypass through misuse of ServerConfig.PublicKeyCallback. Additionally, CVE-2025-22869 introduces a denial of service vulnerability via slow or incomplete key exchanges, and multiple other vulnerabilities have been disclosed in 2025. Upgrade to v0.35.0 or later to address these issues.
🤖 Prompt for AI Agents
In tests/gotests/bench_doc/go.mod around line 18, the dependency
golang.org/x/crypto is pinned to v0.26.0 which is vulnerable (CVE-2024-45337,
CVE-2025-22869, etc.); update the module requirement to golang.org/x/crypto
v0.35.0 or later in go.mod, then run go get golang.org/x/crypto@v0.35.0 (or the
latest safe version) and go mod tidy to update go.sum and vendor files as needed
to ensure the project builds with the patched library.
| func generateQueryParams(docs []Cart, count int) []QueryParams { | ||
| params := make([]QueryParams, count) | ||
|
|
||
| for i := 0; i < count; i++ { | ||
| // Select random documents for query parameters | ||
| doc1 := docs[rand.Intn(len(docs))] | ||
| doc2 := docs[rand.Intn(len(docs))] | ||
| doc3 := docs[rand.Intn(len(docs))] | ||
|
|
||
| item1 := doc1.Items[0] | ||
| item2 := doc2.Items[0] | ||
| item3 := doc3.Items[0] | ||
|
|
||
| params[i] = QueryParams{ | ||
| ExactMatchID: item1.ID, | ||
| RangeMinPrice: item1.Price - 5000, | ||
| RangeMaxPrice: item1.Price + 5000, | ||
| AndQuantity: item1.Quantity, | ||
| AndMinGrams: item1.Grams - 1000, | ||
| OrVariantID1: item1.VariantID, | ||
| OrVariantID2: item2.VariantID, | ||
| ArrayContainsID: item1.ID, | ||
| NestedPrice: item1.Price, | ||
| ComplexMinPrice: item3.Price - 3000, | ||
| ComplexMaxGrams: item3.Grams + 1000, | ||
| ComplexVariantID: item3.VariantID, | ||
| } | ||
| } | ||
|
|
||
| return params | ||
| } |
There was a problem hiding this comment.
Potential issue: Query parameter generation may produce invalid ranges.
Lines 715-718 and 723-724 calculate query ranges by adding/subtracting fixed offsets from randomly selected item values. This could produce negative values for RangeMinPrice (line 715: item1.Price - 5000) or AndMinGrams (line 718: item1.Grams - 1000) if the base values are small.
🔎 Proposed fix to ensure valid ranges
params[i] = QueryParams{
ExactMatchID: item1.ID,
- RangeMinPrice: item1.Price - 5000,
+ RangeMinPrice: max(0, item1.Price - 5000),
RangeMaxPrice: item1.Price + 5000,
AndQuantity: item1.Quantity,
- AndMinGrams: item1.Grams - 1000,
+ AndMinGrams: max(0, item1.Grams - 1000),
OrVariantID1: item1.VariantID,
OrVariantID2: item2.VariantID,
ArrayContainsID: item1.ID,
NestedPrice: item1.Price,
- ComplexMinPrice: item3.Price - 3000,
+ ComplexMinPrice: max(0, item3.Price - 3000),
ComplexMaxGrams: item3.Grams + 1000,
ComplexVariantID: item3.VariantID,
}
+
+func max(a, b int) int {
+ if a > b {
+ return a
+ }
+ return b
+}Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In tests/gotests/bench_doc/main.go around lines 700 to 730, range fields are
computed by subtracting fixed offsets from randomly picked item values which can
produce negative RangeMinPrice or AndMinGrams (and generally invalid min>max);
update the generator to clamp lower bounds to zero (or to the type's minimum
valid value) and ensure min<=max by computing min as max(0, base - offset) and
max as base + offset (or swap/adjust if needed), e.g. perform integer-safe
checks after computing the offsets and adjust values so RangeMinPrice and
AndMinGrams never go negative and all range pairs satisfy min <= max.
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (2)
tests/gotests/bench_doc/go.mod (1)
18-18: Update golang.org/x/crypto to address multiple critical security vulnerabilities.This indirect dependency is affected by several critical CVEs including authorization bypass (CVE-2024-45337), denial of service via slow key exchanges (CVE-2025-22869), and multiple memory-related vulnerabilities in the SSH components. Upgrade to v0.35.0 or later.
#!/bin/bash # Verify the latest safe version of golang.org/x/crypto curl -s "https://proxy.golang.org/golang.org/x/crypto/@v/list" | tail -5tests/gotests/bench_doc/main.go (1)
715-724: Query range calculations may produce unexpected values if document generation changes.While current data generation ensures minimum
Priceof 10000 andGramsof 1000, these calculations lack explicit guards. If the data generation logic changes,RangeMinPrice,AndMinGrams, orComplexMinPricecould become negative.
🧹 Nitpick comments (1)
concourse/scripts/common.sh (1)
286-293: New benchmark function follows established patterns.The function correctly builds and runs the Go benchmark tool with EloqDoc-only mode and cleans up the database afterward. The pushd/popd are balanced.
Note: The database name
benchmark_db_11is hardcoded here and inmain.go(line 30). Consider extracting this to a shared constant or configuration to prevent drift.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
tests/gotests/bench_doc/go.sumis excluded by!**/*.sum
📒 Files selected for processing (4)
concourse/scripts/common.shconcourse/scripts/main.ent.bashtests/gotests/bench_doc/go.modtests/gotests/bench_doc/main.go
🧰 Additional context used
🧬 Code graph analysis (1)
concourse/scripts/main.ent.bash (1)
concourse/scripts/common.sh (7)
launch_eloqdoc(188-210)try_connect(241-262)run_tpcc(270-284)shutdown_eloqdoc(237-239)run_bench_go(286-294)run_jstests(264-268)cleanup_all(68-84)
🪛 Gitleaks (8.30.0)
tests/gotests/bench_doc/main.go
[high] 441-441: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
[high] 475-475: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
🪛 OSV Scanner (2.3.0)
tests/gotests/bench_doc/go.mod
[CRITICAL] 1-1: golang.org/x/crypto 0.26.0: Misuse of connection.serverAuthenticate may cause authorization bypass in golang.org/x/crypto
(GO-2024-3321)
[CRITICAL] 1-1: golang.org/x/crypto 0.26.0: Potential denial of service in golang.org/x/crypto
(GO-2025-3487)
[CRITICAL] 1-1: golang.org/x/crypto 0.26.0: Potential denial of service in golang.org/x/crypto/ssh/agent
(GO-2025-4116)
[CRITICAL] 1-1: golang.org/x/crypto 0.26.0: Unbounded memory consumption in golang.org/x/crypto/ssh
(GO-2025-4134)
[CRITICAL] 1-1: golang.org/x/crypto 0.26.0: Malformed constraint may cause denial of service in golang.org/x/crypto/ssh/agent
(GO-2025-4135)
[CRITICAL] 1-1: golang.org/x/crypto 0.26.0: golang.org/x/crypto/ssh/agent vulnerable to panic if message is malformed due to out of bounds read
[CRITICAL] 1-1: golang.org/x/crypto 0.26.0: golang.org/x/crypto Vulnerable to Denial of Service (DoS) via Slow or Incomplete Key Exchange
[CRITICAL] 1-1: golang.org/x/crypto 0.26.0: golang.org/x/crypto/ssh allows an attacker to cause unbounded memory consumption
[CRITICAL] 1-1: golang.org/x/crypto 0.26.0: Misuse of ServerConfig.PublicKeyCallback may cause authorization bypass in golang.org/x/crypto
🔇 Additional comments (3)
tests/gotests/bench_doc/main.go (1)
1-24: Well-structured benchmarking tool with comprehensive functionality.The implementation includes proper retry logic with exponential backoff, progress reporting, multi-format output support, and cleanup routines. The concurrent document loading with worker pools is a good design choice for I/O-bound operations.
concourse/scripts/common.sh (1)
282-284: Good addition of database cleanup after TPCC run.The
db.dropDatabase()call ensures the TPCC database is cleaned up after the benchmark completes, preventing disk space accumulation across runs.concourse/scripts/main.ent.bash (1)
56-71: Well-structured multi-phase test execution flow.The script now executes three phases (TPCC → Benchmark → JStests), each with its own launch/shutdown cycle. Database cleanup is handled within each test function (
run_tpccdropstpcc,run_bench_godropsbenchmark_db_11), and final cleanup removes the S3 bucket and data folder.
| // Parse command-line flags | ||
| mongoOnly := flag.Bool("mongo-only", false, "Run only MongoDB benchmarks") | ||
| eloqdocOnly := flag.Bool("eloqdoc-only", false, "Run only EloqDoc benchmarks") | ||
|
|
||
| outputFormat := flag.String("output", "table", "Output format: table, json, csv") | ||
| outputFile := flag.String("output-file", "", "Output file path (optional, defaults to stdout for table, or auto-generated filename)") | ||
| flag.Parse() |
There was a problem hiding this comment.
Missing validation for mutually exclusive flags.
The -mongo-only and -eloqdoc-only flags can both be set simultaneously, which would lead to unexpected behavior (only MongoDB would be benchmarked due to the order of checks, but EloqDoc folder would be used for query params generation).
🔎 Proposed fix
mongoOnly := flag.Bool("mongo-only", false, "Run only MongoDB benchmarks")
eloqdocOnly := flag.Bool("eloqdoc-only", false, "Run only EloqDoc benchmarks")
outputFormat := flag.String("output", "table", "Output format: table, json, csv")
outputFile := flag.String("output-file", "", "Output file path (optional, defaults to stdout for table, or auto-generated filename)")
flag.Parse()
+
+ if *mongoOnly && *eloqdocOnly {
+ log.Fatal("Error: -mongo-only and -eloqdoc-only flags are mutually exclusive")
+ }🤖 Prompt for AI Agents
In tests/gotests/bench_doc/main.go around lines 203 to 209, the code parses the
-mongo-only and -eloqdoc-only flags but does not validate that they are mutually
exclusive; add a check immediately after flag.Parse() that if both *mongoOnly
and *eloqdocOnly are true, print a clear error message to stderr (or use
log.Fatalf) explaining the conflict and exit with a non-zero status so the
program does not proceed in an ambiguous state; implement this simple guard and
return before any benchmark setup or folder/query-generation logic runs.
| func generateQueryParams(docs []Cart, count int) []QueryParams { | ||
| params := make([]QueryParams, count) | ||
|
|
||
| for i := 0; i < count; i++ { | ||
| // Select random documents for query parameters | ||
| doc1 := docs[rand.Intn(len(docs))] | ||
| doc2 := docs[rand.Intn(len(docs))] | ||
| doc3 := docs[rand.Intn(len(docs))] | ||
|
|
||
| item1 := doc1.Items[0] | ||
| item2 := doc2.Items[0] | ||
| item3 := doc3.Items[0] |
There was a problem hiding this comment.
Potential panic if docs slice is empty.
If document loading fails or returns no documents, rand.Intn(len(docs)) will panic with "invalid argument to Intn". Add a guard before generating query parameters.
🔎 Proposed fix
func generateQueryParams(docs []Cart, count int) []QueryParams {
+ if len(docs) == 0 {
+ log.Fatal("Error: No documents available for generating query parameters")
+ }
params := make([]QueryParams, count)
for i := 0; i < count; i++ {📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| func generateQueryParams(docs []Cart, count int) []QueryParams { | |
| params := make([]QueryParams, count) | |
| for i := 0; i < count; i++ { | |
| // Select random documents for query parameters | |
| doc1 := docs[rand.Intn(len(docs))] | |
| doc2 := docs[rand.Intn(len(docs))] | |
| doc3 := docs[rand.Intn(len(docs))] | |
| item1 := doc1.Items[0] | |
| item2 := doc2.Items[0] | |
| item3 := doc3.Items[0] | |
| func generateQueryParams(docs []Cart, count int) []QueryParams { | |
| if len(docs) == 0 { | |
| log.Fatal("Error: No documents available for generating query parameters") | |
| } | |
| params := make([]QueryParams, count) | |
| for i := 0; i < count; i++ { | |
| // Select random documents for query parameters | |
| doc1 := docs[rand.Intn(len(docs))] | |
| doc2 := docs[rand.Intn(len(docs))] | |
| doc3 := docs[rand.Intn(len(docs))] | |
| item1 := doc1.Items[0] | |
| item2 := doc2.Items[0] | |
| item3 := doc3.Items[0] |
🤖 Prompt for AI Agents
In tests/gotests/bench_doc/main.go around lines 700 to 711, the
generateQueryParams function blindly uses rand.Intn(len(docs)) which will panic
if docs is empty; add an explicit guard at the start of the function to handle
len(docs) == 0 (return an empty []QueryParams or an error/ log and exit based on
test expectations), and ensure callers handle the empty result; if returning
empty params, also avoid indexing Items without checking doc.Items length by
validating each selected doc has at least one Item before accessing Items[0],
skipping or regenerating selections when necessary.
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (4)
tests/gotests/bench_doc/go.mod (1)
18-18: Update golang.org/x/crypto to address security vulnerabilities.The dependency golang.org/x/crypto v0.26.0 is affected by multiple critical vulnerabilities including CVE-2024-45337 (authorization bypass), CVE-2025-22869 (denial of service), and several other CVEs disclosed in 2025. Upgrade to v0.35.0 or later to address these issues.
Run the following commands to update:
#!/bin/bash cd tests/gotests/bench_doc go get golang.org/x/crypto@v0.35.0 go mod tidytests/gotests/bench_doc/main.go (3)
203-209: Add validation for mutually exclusive flags.The
-mongo-onlyand-eloqdoc-onlyflags can both be set simultaneously, leading to unexpected behavior. Add validation afterflag.Parse()to ensure they are mutually exclusive.🔎 Proposed fix
outputFormat := flag.String("output", "table", "Output format: table, json, csv") outputFile := flag.String("output-file", "", "Output file path (optional, defaults to stdout for table, or auto-generated filename)") flag.Parse() + + if *mongoOnly && *eloqdocOnly { + log.Fatal("Error: -mongo-only and -eloqdoc-only flags are mutually exclusive") + }
700-711: Guard against empty documents slice.If document loading fails or returns no documents,
rand.Intn(len(docs))at lines 705-707 will panic. Add validation at the start of the function.🔎 Proposed fix
func generateQueryParams(docs []Cart, count int) []QueryParams { + if len(docs) == 0 { + log.Fatal("Error: No documents available for generating query parameters") + } params := make([]QueryParams, count)
713-727: Prevent negative values in query ranges.Lines 715, 718, and 723 calculate ranges by subtracting offsets, which can produce negative
RangeMinPrice,AndMinGrams, orComplexMinPriceif base values are small.🔎 Proposed fix to clamp minimum values
+func max(a, b int) int { + if a > b { + return a + } + return b +} + func generateQueryParams(docs []Cart, count int) []QueryParams { params := make([]QueryParams, count) for i := 0; i < count; i++ { // Select random documents for query parameters doc1 := docs[rand.Intn(len(docs))] doc2 := docs[rand.Intn(len(docs))] doc3 := docs[rand.Intn(len(docs))] item1 := doc1.Items[0] item2 := doc2.Items[0] item3 := doc3.Items[0] params[i] = QueryParams{ ExactMatchID: item1.ID, - RangeMinPrice: item1.Price - 5000, + RangeMinPrice: max(0, item1.Price - 5000), RangeMaxPrice: item1.Price + 5000, AndQuantity: item1.Quantity, - AndMinGrams: item1.Grams - 1000, + AndMinGrams: max(0, item1.Grams - 1000), OrVariantID1: item1.VariantID, OrVariantID2: item2.VariantID, ArrayContainsID: item1.ID, NestedPrice: item1.Price, - ComplexMinPrice: item3.Price - 3000, + ComplexMinPrice: max(0, item3.Price - 3000), ComplexMaxGrams: item3.Grams + 1000, ComplexVariantID: item3.VariantID, } }
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
tests/gotests/bench_doc/go.sumis excluded by!**/*.sum
📒 Files selected for processing (4)
concourse/scripts/common.shconcourse/scripts/main.ent.bashtests/gotests/bench_doc/go.modtests/gotests/bench_doc/main.go
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-11-14T03:10:22.027Z
Learnt from: githubzilla
Repo: eloqdata/eloqdoc PR: 279
File: src/mongo/db/dbmain.cpp:0-0
Timestamp: 2025-11-14T03:10:22.027Z
Learning: In this repository, avoid defining --config via gflags in src/mongo/db/dbmain.cpp; MongoDB’s options_parser owns --config. Prefer gflags flags with a distinct prefix (e.g., --data_substrate_config) parsed before options_parser, with options_parser configured to allow unregistered options.
Applied to files:
tests/gotests/bench_doc/main.go
🧬 Code graph analysis (1)
concourse/scripts/main.ent.bash (1)
concourse/scripts/common.sh (7)
launch_eloqdoc(188-210)try_connect(241-262)run_tpcc(270-284)shutdown_eloqdoc(237-239)run_bench_go(286-294)run_jstests(264-268)cleanup_all(68-84)
🪛 Gitleaks (8.30.0)
tests/gotests/bench_doc/main.go
[high] 441-441: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
[high] 475-475: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
🪛 OSV Scanner (2.3.0)
tests/gotests/bench_doc/go.mod
[CRITICAL] 1-1: golang.org/x/crypto 0.26.0: Misuse of connection.serverAuthenticate may cause authorization bypass in golang.org/x/crypto
(GO-2024-3321)
[CRITICAL] 1-1: golang.org/x/crypto 0.26.0: Potential denial of service in golang.org/x/crypto
(GO-2025-3487)
[CRITICAL] 1-1: golang.org/x/crypto 0.26.0: Potential denial of service in golang.org/x/crypto/ssh/agent
(GO-2025-4116)
[CRITICAL] 1-1: golang.org/x/crypto 0.26.0: Unbounded memory consumption in golang.org/x/crypto/ssh
(GO-2025-4134)
[CRITICAL] 1-1: golang.org/x/crypto 0.26.0: Malformed constraint may cause denial of service in golang.org/x/crypto/ssh/agent
(GO-2025-4135)
[CRITICAL] 1-1: golang.org/x/crypto 0.26.0: golang.org/x/crypto/ssh/agent vulnerable to panic if message is malformed due to out of bounds read
[CRITICAL] 1-1: golang.org/x/crypto 0.26.0: golang.org/x/crypto Vulnerable to Denial of Service (DoS) via Slow or Incomplete Key Exchange
[CRITICAL] 1-1: golang.org/x/crypto 0.26.0: golang.org/x/crypto/ssh allows an attacker to cause unbounded memory consumption
[CRITICAL] 1-1: golang.org/x/crypto 0.26.0: Misuse of ServerConfig.PublicKeyCallback may cause authorization bypass in golang.org/x/crypto
🔇 Additional comments (4)
concourse/scripts/common.sh (1)
282-284: LGTM: Proper cleanup after TPCC run.The addition of database cleanup and proper directory return enhances test hygiene and prevents test artifacts from affecting subsequent runs.
concourse/scripts/main.ent.bash (1)
56-71: LGTM: Well-structured multi-phase test orchestration.The reorganization into distinct phases (TPCC → bench → jstests) with proper EloqDoc lifecycle management (launch/connect/shutdown) for each phase is clear and maintainable. The final cleanup ensures no test artifacts are left behind.
tests/gotests/bench_doc/main.go (2)
371-387: LGTM: Robust retry logic with exponential backoff.The retry implementation with exponential backoff (line 375) properly handles transient failures and provides good user feedback through logging. This pattern is consistently applied throughout database operations.
1-1494: Well-architected benchmarking tool.The implementation demonstrates good engineering practices:
- Clear separation between data generation, loading, and benchmarking phases
- Comprehensive metrics collection (percentiles, mean, stddev, ops/sec)
- Progress reporting for long-running operations
- Proper resource cleanup and context cancellation
- Flexible output formats (table/JSON/CSV)
The structure makes it easy to extend with additional benchmark configurations or query patterns.
| run_bench_go() { | ||
| pushd /home/$current_user/workspace/mongo/tests/gotests/bench_doc | ||
| echo "build bench_doc" | ||
| go build | ||
| echo "run bench_doc" | ||
| ./bench_doc -eloqdoc-only | ||
| $PREFIX/bin/eloqdoc-cli benchmark_db_11 --eval "db.dropDatabase()" | ||
| popd | ||
| } |
There was a problem hiding this comment.
Add error handling for build and execution failures.
The function lacks error checking after go build and ./bench_doc, which means compilation or runtime failures will be silently ignored and the script will continue. This could lead to false positives in CI.
🔎 Proposed fix to add error handling
run_bench_go() {
pushd /home/$current_user/workspace/mongo/tests/gotests/bench_doc
echo "build bench_doc"
go build
+ if [ $? -ne 0 ]; then
+ echo "Error: Failed to build bench_doc"
+ popd
+ exit 1
+ fi
echo "run bench_doc"
./bench_doc -eloqdoc-only
+ if [ $? -ne 0 ]; then
+ echo "Error: bench_doc execution failed"
+ popd
+ exit 1
+ fi
$PREFIX/bin/eloqdoc-cli benchmark_db_11 --eval "db.dropDatabase()"
popd
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| run_bench_go() { | |
| pushd /home/$current_user/workspace/mongo/tests/gotests/bench_doc | |
| echo "build bench_doc" | |
| go build | |
| echo "run bench_doc" | |
| ./bench_doc -eloqdoc-only | |
| $PREFIX/bin/eloqdoc-cli benchmark_db_11 --eval "db.dropDatabase()" | |
| popd | |
| } | |
| run_bench_go() { | |
| pushd /home/$current_user/workspace/mongo/tests/gotests/bench_doc | |
| echo "build bench_doc" | |
| go build | |
| if [ $? -ne 0 ]; then | |
| echo "Error: Failed to build bench_doc" | |
| popd | |
| exit 1 | |
| fi | |
| echo "run bench_doc" | |
| ./bench_doc -eloqdoc-only | |
| if [ $? -ne 0 ]; then | |
| echo "Error: bench_doc execution failed" | |
| popd | |
| exit 1 | |
| fi | |
| $PREFIX/bin/eloqdoc-cli benchmark_db_11 --eval "db.dropDatabase()" | |
| popd | |
| } |
🤖 Prompt for AI Agents
concourse/scripts/common.sh lines 286-294: the run_bench_go function currently
runs `go build` and `./bench_doc` without checking for failures; update it to
check the exit status after `go build` and after running `./bench_doc` (or test
executable existence) and exit non‑zero with a clear error message if either
fails (for example: if go build fails echo "bench_doc build failed" and exit 1;
if the binary is missing or `./bench_doc` returns non‑zero echo "bench_doc
execution failed" and exit 1), keeping the existing cleanup/popd behavior.
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (5)
tests/gotests/bench_doc/go.mod (1)
18-18: Updategolang.org/x/cryptoto address critical security vulnerabilities.The dependency
golang.org/x/crypto v0.26.0is affected by multiple critical vulnerabilities identified by OSV Scanner, including authorization bypass (CVE-2024-45337), denial of service (CVE-2025-22869), and unbounded memory consumption issues. Upgrade to at least v0.35.0.cd tests/gotests/bench_doc && go get golang.org/x/crypto@latest && go mod tidyconcourse/scripts/common.sh (1)
286-294: Add error handling forgo buildand./bench_docexecution.The function lacks exit status checks after both commands. If compilation or the benchmark fails, the script will continue silently, potentially masking CI failures.
🔎 Proposed fix
run_bench_go() { pushd /home/$current_user/workspace/mongo/tests/gotests/bench_doc echo "build bench_doc" - go build + go build || { echo "Error: Failed to build bench_doc"; popd; exit 1; } echo "run bench_doc" - ./bench_doc -eloqdoc-only + ./bench_doc -eloqdoc-only || { echo "Error: bench_doc execution failed"; popd; exit 1; } $PREFIX/bin/eloqdoc-cli benchmark_db_11 --eval "db.dropDatabase()" popd }tests/gotests/bench_doc/main.go (3)
203-209: Add validation for mutually exclusive flags.The
-mongo-onlyand-eloqdoc-onlyflags can both be set simultaneously, leading to undefined behavior (MongoDB documents generated but EloqDoc folder used for query params).🔎 Proposed fix
flag.Parse() + + if *mongoOnly && *eloqdocOnly { + log.Fatal("Error: -mongo-only and -eloqdoc-only flags are mutually exclusive") + }
700-711: Add guard for emptydocsslice to prevent panic.If
docsis empty (e.g., document loading fails),rand.Intn(len(docs))will panic with "invalid argument to Intn".🔎 Proposed fix
func generateQueryParams(docs []Cart, count int) []QueryParams { + if len(docs) == 0 { + log.Fatal("Error: No documents available for generating query parameters") + } params := make([]QueryParams, count)
713-726: Clamp range values to prevent negative query parameters.
RangeMinPrice(line 715) andAndMinGrams(line 718) can become negative if base values are small, potentially causing unexpected query behavior.🔎 Proposed fix
params[i] = QueryParams{ ExactMatchID: item1.ID, - RangeMinPrice: item1.Price - 5000, + RangeMinPrice: max(0, item1.Price - 5000), RangeMaxPrice: item1.Price + 5000, AndQuantity: item1.Quantity, - AndMinGrams: item1.Grams - 1000, + AndMinGrams: max(0, item1.Grams - 1000), OrVariantID1: item1.VariantID, OrVariantID2: item2.VariantID, ArrayContainsID: item1.ID, NestedPrice: item1.Price, - ComplexMinPrice: item3.Price - 3000, + ComplexMinPrice: max(0, item3.Price - 3000), ComplexMaxGrams: item3.Grams + 1000, ComplexVariantID: item3.VariantID, }Note: Go 1.21+ has built-in
max(). For earlier versions, define a helper function.
🧹 Nitpick comments (2)
tests/gotests/bench_doc/main.go (2)
1462-1483: Usedeferforclient.Disconnectto ensure cleanup on all code paths.If an error occurs between
mongo.Connectandclient.Disconnect, the connection may leak. Usingdeferensures the connection is always closed.🔎 Proposed fix
client, err := mongo.Connect(ctx, options.Client().ApplyURI(info.uri)) if err != nil { log.Printf("Failed to connect for cleanup: %v", err) continue } + defer client.Disconnect(ctx) coll := client.Database(info.dbName).Collection(info.collection) err = retryOperation(func() error { return coll.Drop(ctx) }, maxRetries) if err != nil { log.Printf("Failed to drop collection %s after %d retries: %v", info.collection, maxRetries, err) } else { fmt.Printf(" ✓ Dropped collection: %s\n", info.collection) } - - client.Disconnect(ctx) }
371-387: Consider adding jitter to exponential backoff.The retry logic uses pure exponential backoff without jitter. For improved reliability in concurrent scenarios, consider adding randomized jitter to prevent synchronized retries.
🔎 Proposed enhancement (optional)
if attempt > 0 { - delay := time.Duration(retryDelayMs*(1<<uint(attempt-1))) * time.Millisecond + baseDelay := retryDelayMs * (1 << uint(attempt-1)) + jitter := rand.Intn(baseDelay / 4) // 0-25% jitter + delay := time.Duration(baseDelay+jitter) * time.Millisecond time.Sleep(delay)
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
tests/gotests/bench_doc/go.sumis excluded by!**/*.sum
📒 Files selected for processing (5)
concourse/scripts/common.shconcourse/scripts/main.bashconcourse/scripts/main.ent.bashtests/gotests/bench_doc/go.modtests/gotests/bench_doc/main.go
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-11-14T03:10:22.027Z
Learnt from: githubzilla
Repo: eloqdata/eloqdoc PR: 279
File: src/mongo/db/dbmain.cpp:0-0
Timestamp: 2025-11-14T03:10:22.027Z
Learning: In this repository, avoid defining --config via gflags in src/mongo/db/dbmain.cpp; MongoDB’s options_parser owns --config. Prefer gflags flags with a distinct prefix (e.g., --data_substrate_config) parsed before options_parser, with options_parser configured to allow unregistered options.
Applied to files:
tests/gotests/bench_doc/main.go
🧬 Code graph analysis (2)
concourse/scripts/main.bash (1)
concourse/scripts/common.sh (7)
launch_eloqdoc(188-210)try_connect(241-262)run_tpcc(270-284)shutdown_eloqdoc(237-239)run_bench_go(286-294)run_jstests(264-268)cleanup_all(68-84)
concourse/scripts/main.ent.bash (1)
concourse/scripts/common.sh (7)
launch_eloqdoc(188-210)try_connect(241-262)run_tpcc(270-284)shutdown_eloqdoc(237-239)run_bench_go(286-294)run_jstests(264-268)cleanup_all(68-84)
🪛 Gitleaks (8.30.0)
tests/gotests/bench_doc/main.go
[high] 441-441: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
[high] 475-475: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
🪛 OSV Scanner (2.3.0)
tests/gotests/bench_doc/go.mod
[CRITICAL] 1-1: golang.org/x/crypto 0.26.0: Misuse of connection.serverAuthenticate may cause authorization bypass in golang.org/x/crypto
(GO-2024-3321)
[CRITICAL] 1-1: golang.org/x/crypto 0.26.0: Potential denial of service in golang.org/x/crypto
(GO-2025-3487)
[CRITICAL] 1-1: golang.org/x/crypto 0.26.0: Potential denial of service in golang.org/x/crypto/ssh/agent
(GO-2025-4116)
[CRITICAL] 1-1: golang.org/x/crypto 0.26.0: Unbounded memory consumption in golang.org/x/crypto/ssh
(GO-2025-4134)
[CRITICAL] 1-1: golang.org/x/crypto 0.26.0: Malformed constraint may cause denial of service in golang.org/x/crypto/ssh/agent
(GO-2025-4135)
[CRITICAL] 1-1: golang.org/x/crypto 0.26.0: golang.org/x/crypto/ssh/agent vulnerable to panic if message is malformed due to out of bounds read
[CRITICAL] 1-1: golang.org/x/crypto 0.26.0: golang.org/x/crypto Vulnerable to Denial of Service (DoS) via Slow or Incomplete Key Exchange
[CRITICAL] 1-1: golang.org/x/crypto 0.26.0: golang.org/x/crypto/ssh allows an attacker to cause unbounded memory consumption
[CRITICAL] 1-1: golang.org/x/crypto 0.26.0: Misuse of ServerConfig.PublicKeyCallback may cause authorization bypass in golang.org/x/crypto
🔇 Additional comments (6)
concourse/scripts/common.sh (1)
282-284: LGTM - Database cleanup after TPCC run.The addition of
db.dropDatabase()after the TPCC run ensures proper cleanup of the test database, andpopdcorrectly returns to the previous directory.concourse/scripts/main.ent.bash (1)
56-71: LGTM - Multi-phase test execution with proper EloqDoc lifecycle management.The restructured flow correctly isolates TPCC, bench, and jstest phases with separate EloqDoc lifecycles. Each phase has its own launch/connect/shutdown cycle, and the internal database cleanup in
run_tpccandrun_bench_goprevents test pollution between phases.concourse/scripts/main.bash (1)
47-62: LGTM - Consistent multi-phase test execution matchingmain.ent.bash.The OSS test flow correctly mirrors the enterprise version with the same three-phase structure (TPCC → bench → jstests), each with its own EloqDoc lifecycle.
tests/gotests/bench_doc/main.go (3)
26-39: LGTM - Configuration constants are well-defined.The constants provide sensible defaults for benchmarking with appropriate retry settings and batch sizes.
732-754: LGTM - Good connection management with appropriate pool settings.The MongoDB client configuration includes sensible pool sizes, timeouts, and proper use of
defer client.Disconnect(ctx)for cleanup.
582-676: LGTM - Well-structured concurrent document loading.The worker pool pattern is correctly implemented with proper channel management, context cancellation handling, and WaitGroup synchronization.
|
Blocked on eloqdata/project_tracker#116 |
Summary by CodeRabbit
New Features
Chores
Bug Fixes / Cleanup
✏️ Tip: You can customize this high-level summary in your review settings.